/*
 * Copyright 2006 Matt Jensen
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.spectaql.metadata;

import org.spectaql.PersistenceAdapter;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Iterator;

/**
 * <p>
 * <code>PersistenceMetadata</code> is the top level of the persistence metadata hierarchy. All entity and property
 * metadata is accessed through an implementor of this interface. The details of instantiation and population of objects
 * implementing this interface are handled by the {@link PersistenceAdapter} implementation in use.
 * </p>
 */
public interface PersistenceMetadata extends Serializable
{
    /**
     * <p>
     * Get an iterator over the friendly names of all entities in the persistence mappings.
     * </p>
     *
     * @return {@link Iterator} over {@link String} entity names.
     */
    public Iterator<String> getEntityNames();

    /**
     * <p>
     * Get the metadata for a given entity class.
     * </p>
     *
     * @param entityClass the entity class.
     * @return {@link EntityMetadata} instance.
     * @throws IllegalArgumentException if the entity does not exist.
     */
    public EntityMetadata getEntity(Class<?> entityClass) throws IllegalArgumentException;

    /**
     * <p>
     * Get the metadata for the entity class with a given friendly name in the persistence mappings.
     * </p>
     *
     * @param entityName the entity name.
     * @return {@link EntityMetadata} instance.
     * @throws IllegalArgumentException if the entity does not exist.
     */
    public EntityMetadata getEntity(String entityName) throws IllegalArgumentException;

    /**
     * <p>
     * Get the metadata for the property with a given accessor method.
     * </p>
     *
     * @param method the accessor method.
     * @return {@link PropertyMetadata} instance.
     * @throws IllegalArgumentException if the property does not exist.
     */
    public PropertyMetadata getPropertyForReadMethod(Method method) throws IllegalArgumentException;

    /**
     * <p>
     * Get the metadata for the property with a given mutator method.
     * </p>
     *
     * @param method the mutator method.
     * @return {@link PropertyMetadata} instance.
     * @throws IllegalArgumentException if the property does not exist.
     */
    public PropertyMetadata getPropertyForWriteMethod(Method method) throws IllegalArgumentException;

    /**
     * <p>
     * Determine whether or not a given class is a mapped entity class.
     * </p>
     * 
     * @param clazz the class.
     * @return <code>boolean</code> indicating whether this is an entity class.
     */
    public boolean isEntityClass(Class<?> clazz);

    /**
     * <p>
     * Determine whether or not a given class is the identifier class for a given entity class.
     * </p>
     * 
     * @param entityClass the entity class.
     * @param clazz the possible identifier class.
     * @return <code>boolean</code> indicating whether this is the identifier class for the entity class.
     * @throws IllegalArgumentException if the given class is not a mapped entity class.
     */
    public boolean isEntityIdentifierClass(Class<?> entityClass, Class<?> clazz) throws IllegalArgumentException;
}
